use bytes::{BufMut, Bytes, BytesMut};

mod package;
mod encode;
mod decode;
pub use package::Proto;
pub use package::Cmd;

pub use encode::BodyEncode;
pub use decode::BodyDecode;

use super::{xor_sum, END, HEAD};

pub trait ToProtoBytes {
    fn to_bytes(self) -> Bytes;
}

impl <T: BodyEncode> ToProtoBytes for Proto<T> {
    
    fn to_bytes(self) -> Bytes {
        let mut buf = BytesMut::new();
        buf.put_u16(HEAD);
        buf.put_u8(0);
        buf.put_u8(self.ty);
        buf.put_u8(self.seq);
        buf.put_u8(self.src);
        buf.put_u8(self.dst);
        self.body.encode(&mut buf);
        let s = xor_sum(&buf[3..]);
        buf.put_u8(s);
        buf.put_u8(END);
        buf[2] = buf.len() as u8;
        buf.freeze()
    }
}


